import { create } from 'zustand';
import { devtools, persist } from 'zustand/middleware';
import { produce } from 'immer';
import { nanoid } from 'nanoid';
import { PageType, LayoutType, ActionType } from '../types';
import type {
  Component,
  Page,
  Model,
  App,
  AppConfig,
  AppHistory,
  HistoryItem
} from '../types';

// 默认主题配置
const defaultTheme = {
  mode: 'light',
  primaryColor: '#1890ff',
  secondaryColor: '#52c41a',
  successColor: '#52c41a',
  errorColor: '#f5222d',
  warningColor: '#faad14',
  infoColor: '#1890ff',
  fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial',
  fontSize: 14,
  borderRadius: 4
};

// 默认导航配置
const defaultNavigation = {
  type: 'sidebar',
  logo: '',
  title: 'Yong 低代码平台',
  collapsed: false,
  theme: 'light',
  showBreadcrumb: true
};

// 应用默认配置
const defaultAppConfig: AppConfig = {
  id: nanoid(),
  name: '未命名应用',
  description: '使用 Yong 低代码平台创建的应用',
  version: '1.0.0',
  theme: defaultTheme as any,
  navigation: defaultNavigation as any
};

// 初始页面
const initialPage: Page = {
  id: 'home',
  name: '首页',
  path: '/',
  type: PageType.NORMAL,
  layoutType: LayoutType.GRID,
  components: []
};

// 初始模型
const initialModel: Model = {
  name: 'book',
  label: '图书',
  fields: [
    { name: 'title', type: 'string' as any, label: '书名', required: true },
    { name: 'author', type: 'string' as any, label: '作者' },
    { name: 'price', type: 'number' as any, label: '价格' },
    { name: 'publishedDate', type: 'date' as any, label: '出版日期' }
  ]
};

// 默认初始应用
const defaultApp: App = {
  config: defaultAppConfig,
  data: {
    pages: {
      home: initialPage
    },
    models: {
      book: initialModel
    },
    currentPageId: 'home'
  }
};

// 状态接口定义
interface AppState {
  app: App;
  history: AppHistory;
  selectedComponentId: string | null;
  
  // 历史记录方法
  undo: () => void;
  redo: () => void;
  pushHistory: (actionType: ActionType, payload: unknown) => void;
  
  // 页面操作方法
  addPage: (page: Page) => void;
  updatePage: (pageId: string, updates: Partial<Page>) => void;
  removePage: (pageId: string) => void;
  setCurrentPageId: (id: string) => void;
  
  // 组件操作方法
  addComponent: (component: Component) => void;
  updateComponent: (componentId: string, updates: Partial<Component>) => void;
  removeComponent: (componentId: string) => void;
  updateComponentProps: (componentId: string, props: Record<string, unknown>) => void;
  updateComponentLayout: (componentId: string, layout: Partial<Component['layout']>) => void;
  updateComponentStyle: (componentId: string, style: Record<string, unknown>) => void;
  setSelectedComponentId: (id: string | null) => void;
  
  // 数据模型方法
  addModel: (model: Model) => void;
  updateModel: (modelName: string, updates: Partial<Model>) => void;
  removeModel: (modelName: string) => void;
  
  // 应用配置方法
  updateAppConfig: (config: Partial<AppConfig>) => void;
  
  // 模板方法
  applyTemplate: (template: { pages: Record<string, Page>, models: Record<string, Model> }) => void;
  
  // 导出/导入方法
  exportAppData: () => string;
  importAppData: (jsonData: string) => void;
}

/**
 * 应用全局状态管理
 */
export const useStore = create<AppState>()(
  devtools(
    persist(
      (set, get) => ({
        // 初始状态
        app: defaultApp,
        history: { past: [], future: [] },
        selectedComponentId: null,

        // 历史记录方法
        pushHistory: (actionType: ActionType, payload: unknown) => {
          const currentState = get();
          set(produce((state) => {
            const historyItem: HistoryItem = {
              actionType,
              payload,
              timestamp: Date.now()
            };
            state.history.past.push(historyItem);
            state.history.future = [];
          }));
        },

        undo: () => {
          const { history } = get();
          if (history.past.length === 0) return;
          
          set(produce((state) => {
            const lastAction = state.history.past.pop()!;
            state.history.future.unshift(lastAction);
            
            // 根据操作类型反向应用变更
            switch (lastAction.actionType) {
              case ActionType.ADD_COMPONENT:
                // 移除最后添加的组件
                const componentId = (lastAction.payload as any).id;
                const pageId = state.app.data.currentPageId;
                const page = state.app.data.pages[pageId];
                state.app.data.pages[pageId].components = page.components.filter(
                  c => c.id !== componentId
                );
                break;
              
              case ActionType.REMOVE_COMPONENT:
                // 恢复删除的组件
                const component = lastAction.payload as Component;
                const pageIdForRestore = state.app.data.currentPageId;
                state.app.data.pages[pageIdForRestore].components.push(component);
                break;
                
              // 其他撤销操作可以按需添加
              
              default:
                // 对于复杂操作，可以存储完整的前一个状态快照进行恢复
                // 这里仅作为示例，完整实现需要考虑所有操作类型
                break;
            }
          }));
        },

        redo: () => {
          const { history } = get();
          if (history.future.length === 0) return;
          
          set(produce((state) => {
            const nextAction = state.history.future.shift()!;
            state.history.past.push(nextAction);
            
            // 根据操作类型重新应用变更
            switch (nextAction.actionType) {
              case ActionType.ADD_COMPONENT:
                // 重新添加组件
                const component = nextAction.payload as Component;
                const pageId = state.app.data.currentPageId;
                state.app.data.pages[pageId].components.push(component);
                break;
              
              case ActionType.REMOVE_COMPONENT:
                // 重新删除组件
                const componentId = (nextAction.payload as Component).id;
                const pageIdForRemove = state.app.data.currentPageId;
                const page = state.app.data.pages[pageIdForRemove];
                state.app.data.pages[pageIdForRemove].components = page.components.filter(
                  c => c.id !== componentId
                );
                break;
                
              // 其他重做操作可以按需添加
                
              default:
                // 对于复杂操作，可以存储完整的前一个状态快照进行恢复
                // 这里仅作为示例，完整实现需要考虑所有操作类型
                break;
            }
          }));
        },

        // 页面操作方法
        addPage: (page) => {
          const { pushHistory } = get();
          set(produce((state) => {
            state.app.data.pages[page.id] = page;
          }));
          pushHistory(ActionType.ADD_PAGE, page);
        },

        updatePage: (pageId, updates) => {
          const { app, pushHistory } = get();
          const currentPage = app.data.pages[pageId];
          
          if (!currentPage) return;
          
          set(produce((state) => {
            state.app.data.pages[pageId] = { 
              ...currentPage, 
              ...updates 
            };
          }));
          pushHistory(ActionType.UPDATE_PAGE, { pageId, updates, previousPage: currentPage });
        },

        removePage: (pageId) => {
          const { app, pushHistory } = get();
          const currentPage = app.data.pages[pageId];
          
          if (!currentPage) return;
          
          set(produce((state) => {
            const newPages = { ...state.app.data.pages };
            delete newPages[pageId];
            state.app.data.pages = newPages;
            
            // 如果删除的是当前页面，则切换到第一个可用页面
            if (state.app.data.currentPageId === pageId) {
              const pageIds = Object.keys(newPages);
              if (pageIds.length > 0) {
                state.app.data.currentPageId = pageIds[0];
              }
            }
          }));
          pushHistory(ActionType.REMOVE_PAGE, { pageId, page: currentPage });
        },

        setCurrentPageId: (id) => {
          set(produce((state) => {
            state.app.data.currentPageId = id;
          }));
        },

        // 组件操作方法
        addComponent: (component) => {
          const { app, pushHistory } = get();
          const pageId = app.data.currentPageId;
          
          set(produce((state) => {
            const page = state.app.data.pages[pageId];
            if (page) {
              page.components.push(component);
            }
          }));
          pushHistory(ActionType.ADD_COMPONENT, component);
        },

        updateComponent: (componentId, updates) => {
          const { app, pushHistory } = get();
          const pageId = app.data.currentPageId;
          const page = app.data.pages[pageId];
          
          if (!page) return;
          
          const componentIndex = page.components.findIndex(c => c.id === componentId);
          if (componentIndex === -1) return;
          
          const previousComponent = page.components[componentIndex];
          
          set(produce((state) => {
            const updatedComponent = {
              ...previousComponent,
              ...updates
            };
            state.app.data.pages[pageId].components[componentIndex] = updatedComponent;
          }));
          pushHistory(ActionType.UPDATE_COMPONENT, { 
            componentId, 
            updates, 
            previousComponent 
          });
        },

        removeComponent: (componentId) => {
          const { app, selectedComponentId, pushHistory } = get();
          const pageId = app.data.currentPageId;
          const page = app.data.pages[pageId];
          
          if (!page) return;
          
          const componentToRemove = page.components.find(c => c.id === componentId);
          if (!componentToRemove) return;
          
          set(produce((state) => {
            state.app.data.pages[pageId].components = page.components.filter(
              c => c.id !== componentId
            );
            
            // 如果删除的是当前选中组件，则清除选择状态
            if (state.selectedComponentId === componentId) {
              state.selectedComponentId = null;
            }
          }));
          pushHistory(ActionType.REMOVE_COMPONENT, componentToRemove);
        },

        updateComponentProps: (componentId, props) => {
          const { app, pushHistory } = get();
          const pageId = app.data.currentPageId;
          const page = app.data.pages[pageId];
          
          if (!page) return;
          
          const componentIndex = page.components.findIndex(c => c.id === componentId);
          if (componentIndex === -1) return;
          
          const previousProps = page.components[componentIndex].props;
          
          set(produce((state) => {
            const component = state.app.data.pages[pageId].components[componentIndex];
            component.props = {
              ...component.props,
              ...props
            };
          }));
          pushHistory(ActionType.UPDATE_COMPONENT_PROPS, {
            componentId,
            props,
            previousProps
          });
        },

        updateComponentLayout: (componentId, layout) => {
          const { app, pushHistory } = get();
          const pageId = app.data.currentPageId;
          const page = app.data.pages[pageId];
          
          if (!page) return;
          
          const componentIndex = page.components.findIndex(c => c.id === componentId);
          if (componentIndex === -1) return;
          
          const previousLayout = page.components[componentIndex].layout;
          
          set(produce((state) => {
            const component = state.app.data.pages[pageId].components[componentIndex];
            component.layout = {
              ...component.layout,
              ...layout
            };
          }));
          pushHistory(ActionType.UPDATE_COMPONENT_LAYOUT, {
            componentId,
            layout,
            previousLayout
          });
        },
        
        updateComponentStyle: (componentId, style) => {
          const { app, pushHistory } = get();
          const pageId = app.data.currentPageId;
          const page = app.data.pages[pageId];
          
          if (!page) return;
          
          const componentIndex = page.components.findIndex(c => c.id === componentId);
          if (componentIndex === -1) return;
          
          const component = page.components[componentIndex];
          const previousStyle = component.styles || {};
          
          set(produce((state) => {
            const updatedComponent = state.app.data.pages[pageId].components[componentIndex];
            updatedComponent.styles = {
              ...(updatedComponent.styles || {}),
              ...style
            };
          }));
          pushHistory(ActionType.UPDATE_COMPONENT_PROPS, {
            componentId,
            style,
            previousStyle
          });
        },

        setSelectedComponentId: (id) => {
          set(produce((state) => {
            state.selectedComponentId = id;
          }));
        },

        // 数据模型方法
        addModel: (model) => {
          const { pushHistory } = get();
          set(produce((state) => {
            state.app.data.models[model.name] = model;
          }));
          pushHistory(ActionType.ADD_MODEL, model);
        },

        updateModel: (modelName, updates) => {
          const { app, pushHistory } = get();
          const currentModel = app.data.models[modelName];
          
          if (!currentModel) return;
          
          set(produce((state) => {
            state.app.data.models[modelName] = {
              ...currentModel,
              ...updates
            };
          }));
          pushHistory(ActionType.UPDATE_MODEL, {
            modelName,
            updates,
            previousModel: currentModel
          });
        },

        removeModel: (modelName) => {
          const { app, pushHistory } = get();
          const modelToRemove = app.data.models[modelName];
          
          if (!modelToRemove) return;
          
          set(produce((state) => {
            const newModels = { ...state.app.data.models };
            delete newModels[modelName];
            state.app.data.models = newModels;
          }));
          pushHistory(ActionType.REMOVE_MODEL, {
            modelName,
            model: modelToRemove
          });
        },
        
        // 应用配置方法
        updateAppConfig: (config) => {
          const { app, pushHistory } = get();
          const previousConfig = app.config;
          
          set(produce((state) => {
            state.app.config = {
              ...state.app.config,
              ...config
            };
          }));
          pushHistory(ActionType.UPDATE_APP_CONFIG, {
            config,
            previousConfig
          });
        },

        // 模板方法
        applyTemplate: (template) => {
          const { pushHistory } = get();
          set(produce((state) => {
            const previousState = {
              pages: state.app.data.pages,
              models: state.app.data.models,
              currentPageId: state.app.data.currentPageId
            };
            
            state.app.data.pages = template.pages;
            state.app.data.models = template.models;
            state.app.data.currentPageId = Object.keys(template.pages)[0];
            state.selectedComponentId = null;
            
            pushHistory(ActionType.APPLY_TEMPLATE, {
              template,
              previousState
            });
          }));
        },
        
        // 导出/导入方法
        exportAppData: () => {
          const { app } = get();
          return JSON.stringify(app, null, 2);
        },
        
        importAppData: (jsonData) => {
          try {
            const data = JSON.parse(jsonData) as App;
            set(produce((state) => {
              state.app = data;
              state.history = { past: [], future: [] };
              state.selectedComponentId = null;
            }));
          } catch (error) {
            console.error('导入应用数据失败:', error);
          }
        }
      }),
      {
        name: 'yong-lowcode-storage',
        partialize: (state) => ({
          app: state.app
        })
      }
    ),
    { name: 'yong-lowcode-store' }
  )
);